package com.qingcheng.controller.untilAndConfigNotBelongToProject;

import org.csource.common.MyException;
import org.csource.common.NameValuePair;
import org.csource.fastdfs.*;
import org.junit.Test;
import org.springframework.core.io.ClassPathResource;

import java.io.ByteArrayInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;

/**
 * FastDFS文件管理
 * 文件上传
 * 文件删除
 * 文件下载
 * 文件信息获取
 * Storage信息获取
 * Tracker信息获取
 */
public class FastDFSClient {
    /**
     * 加载Tracker 连接信息
     */
    static {
        try {
            //查找classpath下的文件路径
            String filename = new ClassPathResource("fdfs_client.conf").getPath();
            //加载Tracker链接信息
            ClientGlobal.init(filename);
        } catch (IOException e) {
            e.printStackTrace();
        } catch (MyException e) {
            e.printStackTrace();
        }
    }

    /**
     * 上传文件
     * @param fastDFSFile
     * @return
     * @throws IOException
     * @throws MyException
     */
    public static String[] upload(FastDFSFile fastDFSFile) throws IOException, MyException {

        //创建一个Tracker访问的客户端对象TrackerClient
        TrackerClient trackerClient = new TrackerClient();
        //创建一个TrackerClient访问的客户端对象TrackerServer,获取连接信息
        TrackerServer trackerServer = trackerClient.getConnection();
        //通过TrackerServer的连接信息可以获取Storage的连接信息，创建StorageClient对象存储Storage的连接信息
        StorageClient storageClient = new StorageClient(trackerServer,null);
        /**
         *通过StorageClient访问Storage,实现文件上传，并且获取文件上传后的存储信息
         *1:上传文件的几节数组
         *2:文件的扩展名 jpg
         *3:附加参数 比如：作者：gao
         *
         * uploads[]
         *      uploads[0]:文件上传所存储的Storage的组名字 group1
         *      uploads[1]:文件存储到Storage上的文件名字 M00/02/44/itheima.jpg
         */
        //附加参数
        NameValuePair[] meta_list = new NameValuePair[1];
        meta_list[0] = new NameValuePair("author",fastDFSFile.getAuthor());
        String[] uploads = storageClient.upload_file(fastDFSFile.getContent(),fastDFSFile.getExt(),meta_list);
        return uploads;
    }

    /**
     * 文件下载,返回字节数组输入流
     * @param groupName 文件的组名
     * @param remoteFileName 文件的存储路径名字
     * @return
     * @throws IOException
     * @throws MyException
     */
    public static InputStream downLoadFile(String groupName,String remoteFileName) throws IOException, MyException {
        //获取StorageClient对象
        StorageClient storageClient = getStorageClient();

        //文件下载，存储到字节数组中
        byte[] buffer = storageClient.download_file(groupName,remoteFileName);
        return new ByteArrayInputStream(buffer);
    }

    /**
     *文件删除
     * @param groupName 文件的组名
     * @param remoteFileName 文件的存储路径名字
     * @throws IOException
     * @throws MyException
     */
    public static void deleteFile(String groupName,String remoteFileName) throws IOException, MyException {
        //获取StorageClient对象
        StorageClient storageClient = getStorageClient();

        //文件删除
        storageClient.delete_file(groupName,remoteFileName);
    }

    /**
     * 获取TrackerServer对象
     * @return
     * @throws IOException
     */
    public static TrackerServer getTrackerServer() throws IOException {
        //创建一个Tracker访问的客户端对象TrackerClient
        TrackerClient trackerClient = new TrackerClient();
        //创建一个TrackerClient访问的客户端对象TrackerServer,获取连接信息
        TrackerServer trackerServer = trackerClient.getConnection();

        return trackerServer;
    }

    /**
     * 获取StorageClient对象
     * @return
     * @throws IOException
     */
    public static StorageClient getStorageClient() throws IOException {
        //创建一个Tracker访问的客户端对象TrackerClient
        TrackerClient trackerClient = new TrackerClient();
        //创建一个TrackerClient访问的客户端对象TrackerServer,获取连接信息
        TrackerServer trackerServer = trackerClient.getConnection();
        //通过TrackerServer的连接信息可以获取Storage的连接信息，创建StorageClient对象存储Storage的连接信息
        StorageClient storageClient = new StorageClient(trackerServer,null);

        return storageClient;
    }

    /**
     * 获取Tracker信息
     * IP地址,Http端口
     * @return
     */
    public static String getTrackerInfo() throws IOException {
        //获取TrackerServer对象
        TrackerServer trackerServer = getTrackerServer();

        //Tracker的IP,Http端口
        //tracker_http_port和tomcat的端口一样，估计和注册一样，tomcat优先获取端口，所有nginx代理的端口我修改为8081
//        int tracker_http_port = ClientGlobal.getG_tracker_http_port();
        String ip = trackerServer.getInetSocketAddress().getHostString();
        String url = "http://"+ip+":"+"8081";

        return url;
    }

    /**
     * 获取Storage信息
     * @return
     * @throws IOException
     */
    public static StorageServer getStorageServer() throws IOException {
        //创建一个Tracker访问的客户端对象TrackerClient
        TrackerClient trackerClient = new TrackerClient();

        //创建一个TrackerClient访问的客户端对象TrackerServer,获取连接信息
        TrackerServer trackerServer = trackerClient.getConnection();

        //获取Storage信息
        return trackerClient.getStoreStorage(trackerServer);
    }

    /**
     * 获取该文件的Storage的IP和端口信息
     * @param groupName
     * @param remoteFileName
     * @return
     * @throws IOException
     */
    public static ServerInfo[] getServerInfo(String groupName,String remoteFileName) throws IOException {
        //创建一个Tracker访问的客户端对象TrackerClient
        TrackerClient trackerClient = new TrackerClient();

        //创建一个TrackerClient访问的客户端对象TrackerServer,获取连接信息
        TrackerServer trackerServer = trackerClient.getConnection();

        //获取StorageIp和端口信息
        return trackerClient.getFetchStorages(trackerServer,groupName,remoteFileName);
    }

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

    /**
     * 测试 下载文件
     */
    @Test
    public void testDownloadFile() throws IOException, MyException {
        //获取StorageClient对象
        StorageClient storageClient = getStorageClient();

        //获取文件信息
        FileInfo fileInfo =storageClient.get_file_info("group1","M00/00/00/wKjTh1_uD9aAIBd_AAEmqkotx98634.jpg");
        System.out.println("文件所在服务器的IP地址:"+fileInfo.getSourceIpAddr());
        System.out.println("可能为文件大小:"+fileInfo.getFileSize()+"KB");
        //文件下载
        InputStream is = downLoadFile("group1","M00/00/00/wKjTh1_tnt-AC8OKAANAKgI7DIU413.jpg");
        //将文件写入到本地磁盘
        FileOutputStream os = new FileOutputStream("D:1.jpg");
        //定义一个缓冲区
        byte[] buffer = new byte[1024];
        //写入到文件
        while(is.read(buffer)!=-1){
            os.write(buffer);
        }
        os.flush();
        os.close();
        is.close();
        System.out.println("下载成功");
    }

    /**
     * 测试  删除文件
     * @throws IOException
     * @throws MyException
     */
    @Test
    public void testDelete() throws IOException, MyException {
        deleteFile("group1","M00/00/00/wKjTh1_t1BaAcQnMAAAkQLilWjI873.jpg");
    }

    /**
     * 测试  获取Storage信息
     * @throws IOException
     */
    @Test
    public void testStorageServer() throws IOException {
        //获取StorageServer
        StorageServer storageServer = getStorageServer();

        System.out.println(storageServer.getStorePathIndex());
        System.out.println(storageServer.getInetSocketAddress().getHostString());
        System.out.println(storageServer.getInetSocketAddress().getPort());
    }

    /**
     * 获取该文件的Storage的IP和端口信息
     * @throws IOException
     */
    @Test
    public void testGetServerInfo() throws IOException {
        ServerInfo[] groups = getServerInfo("group1","M00/00/00/wKjTh1_t1BaAcQnMAAAkQLilWjI873.jpg");

        for(ServerInfo group: groups){
            System.out.println(group.getIpAddr());
            System.out.println(group.getPort());
        }
    }

}
